package com.fone.player.storage.download;

import java.util.LinkedList;
import java.util.List;

import android.app.ActivityManager;
import android.app.ActivityManager.RunningServiceInfo;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.os.Message;
import android.os.RemoteException;
import android.text.format.Formatter;
import android.widget.Toast;

import com.fone.player.R;
import com.fone.player.bean.MemoryData;
import com.fone.player.constant.FoneConstant;
import com.fone.player.entity.Download;
import com.fone.player.entity.OfflineCache;
import com.fone.player.storage.SharedPreferenceModule;
import com.fone.player.storage.StorageConfig;
import com.fone.player.storage.StorageModule;
import com.fone.player.util.FoneUtil;
import com.fone.player.util.L;
import com.fone.player.util.SystemUtil;

import de.greenrobot.event.EventBus;

/**
 * 
 * CacheDownload 流程 DownloadViewControl(UI) <-----> (管理层)CacheDownloadManager
 * <-----> (消息传递层 aidl)DownloadMSGProtocol <----->
 * (service层)CacheDownloadService <----->CacheMessageHandler <-------->
 * fone_service
 * 
 * @author Administrator
 * 
 */
public class CacheDownloadManager {

	private static final String TAG = CacheDownloadManager.class
			.getSimpleName();

	private static IDownloadService mICacheDownloadServiceAIDL = null;
	private static Context mContext;
	private ServiceConnection mServiceConnection = null;
	// 延迟操作队列
	private LinkedList<DelayOperate> mDelayOperateList = new LinkedList<CacheDownloadManager.DelayOperate>();
	private long mFreeSpaceSize = 0;
	private long mTotalSpaceSize = 0;

	public static void init(Context context) {
		mContext = context;
	}

	private static final CacheDownloadManager mCacheDownloadManager = new CacheDownloadManager();;

	private CacheDownloadManager() {
		EventBus.getDefault().register(this);
	}

	public static CacheDownloadManager getInstance() {

		return mCacheDownloadManager;
	}

	public int addDownloadFile(Download download) {

		L.v(TAG, "addDownloadFile", "start");

		try {
			if (mICacheDownloadServiceAIDL == null) {
				w(TAG, "addDownloadFile", "mICacheDownloadServiceAIDL="
						+ mICacheDownloadServiceAIDL);
				// 启动服务
				startCacheService();
				return 0;
			}

			return mICacheDownloadServiceAIDL.addFile(download);

		} catch (RemoteException e) {
			String message = "";
			if (e != null) {
				e.printStackTrace();
				message = e.getMessage();
			}
			e(TAG, "addDownloadFile", "RemoteException " + message);
		}
		return -2;
	}

	public int updateDownloadFile(Download download) {
		try {
			if (mICacheDownloadServiceAIDL == null) {
				w(TAG, "updateDownloadFile", "mICacheDownloadServiceAIDL="
						+ mICacheDownloadServiceAIDL);
				// 启动服务
				startCacheService();
				return 0;
			}

			v(TAG, "updateDownloadFile", "start");

			return mICacheDownloadServiceAIDL.updateFile(download);

		} catch (RemoteException e) {
			String message = "";
			if (e != null) {
				e.printStackTrace();
				message = e.getMessage();
			}
			e(TAG, "updateDownloadFile", "RemoteException " + message);
		}
		return -2;
	}

	public void pauseFile(Download download) {

	}

	public void deleteFile(Download download) {

	}

	/**
	 * 
	 * 添加缓存文件
	 * 
	 * @param offlineCacheFileList
	 *            缓存文件列表
	 * @return void
	 */
	public void addCacheList(List<OfflineCache> offlineCacheFileList) {

		// 检查网络
		if (!checkNetwork()) {
			return;
		}

		// 判断存储空间
		if (checkSingleStorageSpace()) {
			return;
		}

		if (mICacheDownloadServiceAIDL == null) {
			w(TAG, "addCacheList", "mICacheDownloadServiceAIDL="
					+ mICacheDownloadServiceAIDL);
			// 添加一个延迟操作(等待service启动后执行)
			DelayOperate delayOperate = new DelayOperate();
			delayOperate.mOfflineCacheList = offlineCacheFileList;
			mDelayOperateList.add(delayOperate);
			// 开启service
			startCacheService();
			return;
		}

		v(TAG, "addCacheList", "start size=" + offlineCacheFileList.size());
		try {

			mICacheDownloadServiceAIDL.addCacheList(offlineCacheFileList);

		} catch (RemoteException e) {
			e.printStackTrace();
		}

		v(TAG, "addCacheList", "end");

	}

	public void pauseCacheAll(boolean isUpdateDownloadState) {

		try {
			if (mICacheDownloadServiceAIDL == null) {
				w(TAG, "pauseCacheAll", "mICacheDownloadServiceAIDL="
						+ mICacheDownloadServiceAIDL);
				// 启动服务
				startCacheService();
				return;
			}

			v(TAG, "pauseCacheAll", "start");

			mICacheDownloadServiceAIDL.pauseCacheAll(isUpdateDownloadState);

		} catch (RemoteException e) {
			String message = "";
			if (e != null) {
				e.printStackTrace();
				message = e.getMessage();
			}
			e(TAG, "pauseCacheAll", "RemoteException " + message);
		}
	}

	public void pauseCache(OfflineCache offlineCache) {

		try {
			if (mICacheDownloadServiceAIDL == null) {
				w(TAG, "pauseCache", "mICacheDownloadServiceAIDL="
						+ mICacheDownloadServiceAIDL);
				// 启动服务
				startCacheService();
				return;
			}

			mICacheDownloadServiceAIDL.pauseCache(offlineCache);

		} catch (RemoteException e) {
			String message = "";
			if (e != null) {
				e.printStackTrace();
				message = e.getMessage();
			}
			e(TAG, "pauseCache", "RemoteException " + message);
		}
	}

	/**
	 * 
	 * 删除下载的缓存(批量删除后,手动调用getCacheAll)
	 * 
	 * @param offlineCache
	 *            缓存对象
	 * @param isCacheing
	 *            是否正在下载
	 * @param isBatch
	 *            是否批量下载
	 * @return void
	 */
	public void deleteCache(List<OfflineCache> offlineCacheList) {

		try {
			if (mICacheDownloadServiceAIDL == null) {
				w(TAG, "deleteCache", "mICacheDownloadServiceAIDL="
						+ mICacheDownloadServiceAIDL);
				// 启动服务
				startCacheService();

			} else {

				v(TAG, "deleteCache", "start");
				mICacheDownloadServiceAIDL.deleteCache(offlineCacheList);
			}

		} catch (RemoteException e) {
			String message = "";
			if (e != null) {
				e.printStackTrace();
				message = e.getMessage();
			}
			e(TAG, "deleteCache", "RemoteException=" + message);
		}

	}

	public void startCache(OfflineCache offlineCache) {

		if (mICacheDownloadServiceAIDL == null) {
			w(TAG, "startCache", "mICacheDownloadServiceAIDL="
					+ mICacheDownloadServiceAIDL);
			// 启动服务
			startCacheService();
			return;
		}

		try {
			v(TAG, "startCache", "start");

			mICacheDownloadServiceAIDL.startCache(offlineCache);

		} catch (RemoteException e) {
			String message = "";
			if (e != null) {
				e.printStackTrace();
				message = e.getMessage();
			}
			e(TAG, "startCache", "RemoteException " + message);
		}
	}

	public void startCacheAll() {
		// 检查网络
		if (!checkNetwork()) {
			return;
		}

		// 判断存储空间
		if (checkSingleStorageSpace()) {
			return;
		}
		if (mICacheDownloadServiceAIDL == null) {
			w(TAG, "startCacheAll", "mICacheDownloadServiceAIDL="
					+ mICacheDownloadServiceAIDL);
			// 启动服务
			startCacheService();
			return;
		}
		v(TAG, "startCacheAll", "start");
		try {
			mICacheDownloadServiceAIDL.startCacheAll();
		} catch (RemoteException e) {
			String message = "";
			if (e != null) {
				e.printStackTrace();
				message = e.getMessage();
			}
			e(TAG, "startCacheAll", "RemoteException " + message);
		}
	}

	/**
	 * 检查网络
	 */
	public boolean checkNetwork() {
		// 判断网络
		if (DownloadUtil.getNetType() == StorageModule.MSG_NO_NETWORK_TYPE) {
			// 暂时不提示,需要时再解开
			// Message msg = new Message();
			// msg.what = StorageModule.MSG_NO_NETWORK_TYPE;
			// EventBus.getDefault().post(msg);
			return false;
		}
		return true;
	}

	/**
	 * 
	 * 检查存储空间(多次检测)
	 * 
	 * @param currentSize本次下载的大小
	 * @return boolean
	 */
	public synchronized boolean checkManyStorageSpace(long currentSize) {
		boolean isLimit = false;
		long limitSize = SharedPreferenceModule.getInstance().getLong(
				FoneConstant.TMP_LIMIT_SIZE);

		if (mFreeSpaceSize == 0) {
			mFreeSpaceSize = DownloadUtil.getStoreFreeSpaceByte();
		} else {

			// 减去当前下载大小
			mFreeSpaceSize = mFreeSpaceSize - currentSize;

		}

		if (mFreeSpaceSize <= limitSize) {
			long oldLimitSize = SharedPreferenceModule.getInstance().getLong(
					FoneConstant.TMP_LIMIT_OLD_SIZE);
			// 判断旧的上限是否跟新的上限相同,相同不进行提示,不相同提示
			if (oldLimitSize != limitSize) {
				SharedPreferenceModule.getInstance().setLong(
						FoneConstant.TMP_LIMIT_OLD_SIZE, limitSize);
				Message msg = new Message();
				Bundle bundle = new Bundle();
				bundle.putBoolean(OfflineCache.OFFLINE_CACHE_IS_PAUSE, true);
				msg.setData(bundle);
				msg.what = StorageModule.MSG_MIN_SPACE;
				EventBus.getDefault().post(msg);
				e(TAG, "checkManyStorageSpace",
						"SDCard limit  StorageModule.MSG_MIN_SPACE");
			}
			e(TAG,
					"checkManyStorageSpace",
					"SDCard limit limitSize="
							+ Formatter.formatFileSize(mContext, limitSize)
							+ " mFreeSpaceSize="
							+ Formatter
									.formatFileSize(mContext, mFreeSpaceSize));
			isLimit = true;
		} else {
			isLimit = false;
		}

		// 发送实时存储进度信息
		if (mTotalSpaceSize == 0) {
			mTotalSpaceSize = DownloadUtil.getStoreTotalSpaceByte();
		}

		int stroagePrecents = 0;
		if (mTotalSpaceSize == 0) {
			stroagePrecents = 0;
		} else {
			stroagePrecents = (int) (100 * (mTotalSpaceSize - mFreeSpaceSize) / mTotalSpaceSize);
		}

		String spaceLeft = SystemUtil.getInstance().getFreeSpaceFormat(
				mFreeSpaceSize);
		Message message = new Message();
		MemoryData memoryData = new MemoryData();
		memoryData.setSpaceLeft(spaceLeft);
		memoryData.setStroagePrecents(stroagePrecents);

		message.what = StorageModule.MSG_STORAGE_SPACE_PROGRESS;
		message.obj = memoryData;
		EventBus.getDefault().post(message);

		return isLimit;
	}

	/**
	 * 
	 * 检查存储空间(仅限检测一次)
	 * 
	 * @return boolean
	 */
	public synchronized boolean checkSingleStorageSpace() {

		boolean isLimit = false;

		long limitSize = SharedPreferenceModule.getInstance().getLong(
				FoneConstant.TMP_LIMIT_SIZE);

		mFreeSpaceSize = DownloadUtil.getStoreFreeSpaceByte();

		if (mFreeSpaceSize <= limitSize) {
			Message msg = new Message();
			msg.what = StorageModule.MSG_MIN_SPACE;
			EventBus.getDefault().post(msg);
			e(TAG, "checkSingleStorageSpace",
					"SDCard limit StorageModule.MSG_MIN_SPACE  limitSize="
							+ Formatter.formatFileSize(mContext, limitSize));
			isLimit = true;
		} else {
			isLimit = false;
		}

		// 发送实时存储进度信息
		mTotalSpaceSize = DownloadUtil.getStoreTotalSpaceByte();

		int stroagePrecents = 0;
		if (mTotalSpaceSize == 0) {
			stroagePrecents = 0;
		} else {
			stroagePrecents = (int) (100 * (mTotalSpaceSize - mFreeSpaceSize) / mTotalSpaceSize);
		}

		String spaceLeft = SystemUtil.getInstance().getFreeSpaceFormat(
				mFreeSpaceSize);
		Message message = new Message();
		MemoryData memoryData = new MemoryData();
		memoryData.setSpaceLeft(spaceLeft);
		memoryData.setStroagePrecents(stroagePrecents);

		message.what = StorageModule.MSG_STORAGE_SPACE_PROGRESS;
		message.obj = memoryData;
		EventBus.getDefault().post(message);

		return isLimit;
	}

	public void onEventMainThread(Message msg) {
		String text = "";
		Bundle bundle = null;
		switch (msg.what) {
		case StorageModule.MSG_ADD_CACHE_SUCCESS:
			int count = msg.arg1;
			text = "已添加" + count + "部到缓存序列";
			v(TAG, "onEventMainThread", text);
			// Toast.makeText(mContext, text, Toast.LENGTH_LONG).show();
			break;
		case StorageModule.MSG_DOWNLOAD_PREPARE_ONLINE_CACHE_SUCCESS:
			synchronized (TAG) {
				// 边下边播,已下载15%以上
				boolean tip = SharedPreferenceModule.getInstance().getBoolean(
						"cache_online_success");
				if (!tip) {

					text = "您缓存的视频可以播放了";
					Toast.makeText(mContext, text, Toast.LENGTH_LONG).show();
					v(TAG, "onEventMainThread", text);
				}
				// 保存状态,重复cid不提示
				SharedPreferenceModule.getInstance().setBoolean(
						String.valueOf("cache_online_success"), true);
			}
			break;
		case StorageModule.MSG_NO_NETWORK_TYPE:
			// 暂停所有
			// StorageModule.getInstance().pauseAllCache();
			v(TAG, "onEventMainThread", "MSG_NO_NETWORK_TYPE");
			// 无网
			FoneUtil.showToast(mContext, R.string.no_network_toast);

			break;
		case StorageModule.MSG_WIFI_NETWORK_TYPE:
			v(TAG, "onEventMainThread", "MSG_WIFI_NETWORK_TYPE");
			// 开启所有
			StorageModule.getInstance().startAllCache();
			// 您当前处于wifi网络环境下
			FoneUtil.showToast(mContext, R.string.network_wifi_toast);

			break;
		case StorageModule.MSG_2G_NETWORK_TYPE:
		case StorageModule.MSG_3G_NETWORK_TYPE:
		case StorageModule.MSG_4G_NETWORK_TYPE:

			// 获取收藏和缓存界面的"仅wifi缓存按钮"切换状态
			boolean isAutoDownload = SharedPreferenceModule.getInstance()
					.getBoolean(FoneConstant.AUTO_DOWNLOAD_FLAG_SP, true);
			v(TAG, "onEventMainThread",
					"MSG_UNWIFI_NETWORK_TYPE isAutoDownload=" + isAutoDownload);
			// 判断是否下载
			if (isAutoDownload) {

				// 暂停所有(仅wifi开)
				StorageModule.getInstance().pauseAllCache(true);

			} else {
				// 开启所有(仅wifi关)
				StorageModule.getInstance().startAllCache();

			}
			// 您当前处于非wifi网络环境下，继续使用可能产生流量
			FoneUtil.showToast(mContext, R.string.network_unwifi_toast);
			break;
		case StorageModule.MSG_MIN_SPACE:
			bundle = msg.getData();
			if (bundle != null) {
				boolean isPause = bundle
						.getBoolean(OfflineCache.OFFLINE_CACHE_IS_PAUSE);
				if (isPause) {
					// 暂停所有
					StorageModule.getInstance().pauseAllCache(true);
				}

			}

			text = "存储空间不足，请进行清理";
			FoneUtil.showToast(mContext, text);
			break;
		case StorageModule.MSG_MAX_DOWNLOAD:
			text = "最多只能缓存到100集，请稍后添加";
			Toast.makeText(mContext, text, Toast.LENGTH_SHORT).show();
			break;
		default:
			break;
		}
	}

	public void startCacheService() {
		v(TAG, "startCacheService", "start");

		// 打印栈
		StorageModule.getInstance().writeStackTrace();

		if (isServiceStarted(mContext, CacheDownloadService.class)) {
			v(TAG, "startCacheService", "isServiceStarted=true");
			return;
		}

		Intent serviceIntent = new Intent();
		serviceIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
		serviceIntent.setClass(mContext, CacheDownloadService.class);
		// mContext.startService(serviceIntent);
		// v(TAG, "startCacheService", "startService(Intent) start");
		if (mICacheDownloadServiceAIDL == null) {
			v(TAG, "startCacheService", "mICacheDownloadServiceAIDL ==null");

			v(TAG, "startCacheService", "bindService");
			mServiceConnection = new ServiceConnection() {

				@Override
				public void onServiceDisconnected(ComponentName name) {
					w(TAG, "onServiceDisconnected", "service disconnected");
					try {
						if (mICacheDownloadServiceAIDL != null) {
							mICacheDownloadServiceAIDL
									.unregisterCallback(DownloadMessageProtocol.mCallback);
						}
					} catch (RemoteException e) {
						e.printStackTrace();
					}

					v(TAG, "onServiceDisconnected",
							"force mICacheDownloadServiceAIDL = null");

					mICacheDownloadServiceAIDL = null;

					startCacheService();
				}

				@Override
				public void onServiceConnected(ComponentName name,
						IBinder binder) {
					v(TAG, "onServiceConnected", "service connected");
					mICacheDownloadServiceAIDL = IDownloadService.Stub
							.asInterface(binder);
					v(TAG, "onServiceConnected", "mICacheDownloadServiceAIDL="
							+ mICacheDownloadServiceAIDL);
					try {
						if (mICacheDownloadServiceAIDL != null) {
							v(TAG, "onServiceConnected", "registerCallback SUC");
							mICacheDownloadServiceAIDL
									.registerCallback(DownloadMessageProtocol.mCallback);

							if (mDelayOperateList != null
									&& mDelayOperateList.size() > 0) {

								// 取出延迟操作,进行执行
								DelayOperate delayOperate = mDelayOperateList
										.removeFirst();
								if (delayOperate != null) {
									addCacheList(delayOperate.mOfflineCacheList);
								}

							}

						} else {
							v(TAG, "onServiceConnected",
									"mICacheDownloadServiceAIDL==null");
						}
					} catch (RemoteException e) {
						e.printStackTrace();
					}
				}
			};
			mContext.bindService(serviceIntent, mServiceConnection,
					Context.BIND_AUTO_CREATE);
		} else {
			v(TAG, "startCacheService", "mICacheDownloadServiceAIDL !=null");
		}
	}

	public void stopCacheService() {
		v(TAG, "stopCacheService", "start");
		if (isServiceStarted(mContext, CacheDownloadService.class)) {
			mContext.unbindService(mServiceConnection);
		}
	}

	public boolean isServiceStarted(Context context,
			Class<CacheDownloadService> clazz) {
		v(TAG, "isStarted", "isStarted method start");

		if (null == mICacheDownloadServiceAIDL) {
			return false;
		}

		boolean shown = false;

		String className = clazz.getName();
		ActivityManager activityManager = (ActivityManager) context
				.getSystemService(Context.ACTIVITY_SERVICE);
		List<ActivityManager.RunningServiceInfo> serviceList = activityManager
				.getRunningServices(Integer.MAX_VALUE);

		for (int i = 0; !shown && i < serviceList.size(); i++) {
			RunningServiceInfo serviceInfo = serviceList.get(i);
			ComponentName serviceName = serviceInfo.service;

			if (serviceName.getClassName().equals(className)) {
				// v(TAG, "Service " + className + " running ! ");
				shown = true;
			}
		}
		v(TAG, "isServiceStarted", "isRuning=" + String.valueOf(shown));

		return shown;
	}

	public static class DelayOperate {
		public List<OfflineCache> mOfflineCacheList;
	}

	private void v(String tag, String type, String msg) {
		if (StorageConfig.CACHE_DOWNLOAD_MANAGER_LOG) {
			L.v(tag, type, msg);
		}
	}

	private void w(String tag, String type, String msg) {
		if (StorageConfig.CACHE_DOWNLOAD_MANAGER_LOG) {
			L.w(tag, type, msg);
		}
	}

	private void e(String tag, String type, String msg) {
		if (StorageConfig.CACHE_DOWNLOAD_MANAGER_LOG) {
			L.e(tag, type, msg);
		}
	}
}
